home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / hardware.swg / 0036_Rebooting PC.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-08-25  |  3.9 KB  |  100 lines

  1. {
  2.  Q: How is the code for rebooting the PC written in Turbo Pascal?
  3.  
  4.  A: This item draws from the information and the C-code example in
  5. Stan Brown's comp.os.msdos.programmer FAQ, garbo.uwasa.fi:
  6. /pc/doc-net/faqp9317.zip (at the time of writing this), from
  7. memory.lst and interrup.b in /pc/programming/inter39b.zip, and from
  8. /pc/programming/helppc21.zip. The Turbo Pascal code is my adaptation
  9. of the C-code. It is not a one-to-one replica.
  10.    The usually advocated warm-boot method is storing $1234 in the
  11. word at $0040:$0072 and jumping to address $FFFF:$0000. The problem
  12. with this approach is that files must first be closed, potential
  13. caches flushed. This is how to do this
  14. }
  15.  
  16.   procedure REBOOT;
  17.   label next;
  18.   var regs  : registers;
  19.       i     : byte;
  20.       ticks : longint;
  21.   begin
  22.     {... "press" alt-ctrl ...}
  23.     mem[$0040:$0017] := mem[$0040:$0017] or $0C;  { 00001100 }
  24.     {... "press" del, try a few times ...}
  25.     for i := 1 to 10 do
  26.       begin
  27.         FillChar (regs, sizeOf(regs), 0);  { initialize }
  28.         regs.ah := $4F;  { service number }
  29.         regs.al := $53;  { del key's scan code }
  30.         regs.flags := FCarry;  { "sentinel for ignoring key" }
  31.         Intr ($15, regs);
  32.         {... check if the del key registered, if not retry ...}
  33.         if regs.flags and Fcarry > 0 then goto next;
  34.         {... waste some time, watch out for midnight ...}
  35.         ticks := MemL [$0040:$006C];
  36.         repeat until (MemL[$0040:$006C] - ticks > 3) or
  37.                      (MemL[$0040:$006C] - ticks < 0)
  38.     end; {for}
  39.     exit;
  40.   next:
  41.     {... disk reset: writes all modified disk buffers to disk ...}
  42.     FillChar (regs, sizeOf(regs), 0);
  43.     regs.ah := $0D;
  44.     MsDos (regs);
  45.     {... set post-reset flag, use $0000 instead of $1234 for coldboot ...}
  46.     memW[$0040:$0072] := $1234;
  47.     {... jump to $FFFF:0000 BIOS reset ...}
  48.     Inline($EA/$00/$00/$FF/$FF);
  49.   end;  (* reboot *)
  50. {
  51. One slight problem with this approach is that the keyboard intercept
  52. interrupt $15 service $4F requires at least an AT according to
  53. inter39b.zip. A simple test based on "FFFF:E byte ROM machine id"
  54. (the previous definition is from helppc21.zip) is:
  55. }
  56.   function ISATFN : boolean;
  57.   begin
  58.      case Mem[$F000:$FFFE] of
  59.        $FC, $FA, $F8 : isatfn := true;
  60.        else isatfn := false;
  61.      end; {case}
  62.   end;  (* isatfn *)
  63. {
  64. For a more comprehensive test use CPUFN "Get the type of the
  65. processor chip" from TSUNTH in garbo.uwasa.fi:/pc/ts/tspa*.zip or
  66. see the TP + ASM code in Michael Ticher (1992), PC Intern System
  67. Programming, pp. 725-727.
  68.    An addition by Per Bergland (d6caps@dtek.chalmers.se): I recently
  69. downloaded the FAQ for this newsgroup, and studied the code for
  70. rebooting a PC. The problem with that code (calling FFFF:0000) is
  71. that it will not work in protected mode programs such as those
  72. compiled for Windows or BP7 DPMI, or even in a DOS program run in a
  73. Windows DOS session. The solution provided has been tested on
  74. various COMPAQ PC:s, but I think it will work on any AT-class
  75. machine. It involves using the 8042 keyboard controller chip output
  76. pin 0, which is physically connected to the reset pin of the CPU.
  77. There is unfortunately no way to perform a "warm" reboot this way,
  78. and the warnings about disk caches etc apply to this code, too (see
  79. FAQ). The code is written in BP7 assembly lingo, because that's what
  80. I normally write code in, but anyone could rewrite it in C or high
  81. level Pascal.
  82. }
  83.  
  84.   UNIT Reboot;
  85.   INTERFACE
  86.     procedure DoReboot;
  87.   IMPLEMENTATION
  88.     procedure DoReboot;assembler;
  89.     asm
  90.       cli
  91.   @@WaitOutReady:       { Busy-wait until 8042 is ready for new command}
  92.       in al,64h         { read 8042 status byte}
  93.       test al,00000010b { Bit 1 of status indicates input buffer full }
  94.       jnz @@WaitOutReady
  95.       mov al,0FEh       { Pulse "reset" = 8042 pin 0 }
  96.       out 64h,al
  97.       { The PC will reboot now }
  98.     end;
  99.   END.
  100.